<?php

/**
 * Vega Framework
 *
 * @url http://vega.com.vn
 * @url http://clip.vn
 */

class Vega_Log_Writer
{
	const LOG			= 'log';
	protected
		$_file 			= null,
		$_format		= null,
		$_fHandle		= null,
		$_filesize		= null,
		$_maxFilesize	= 1000, 	// split file if filesize is greater than 10Mb
		$_option 		= array();
        
	public function __construct($file = "", $mode = 'a', $compress = true)
	{
		require_once 'Vega/Log/Exception.php';
        
        $config = Vega_App::getInstance()->coreConfig;
        $this->_maxFilesize = isset($config['logging']['file_size_limit']) ? $config['logging']['file_size_limit'] : $this->_maxFilesize;
		
		if (!isset($file))
	    {
	      	throw new Vega_Log_Exception('{'.__CLASS__.'} File must be specified');
	    }
	
	    $dir = dirname($file);
	    
		if (!is_writable($dir) || (file_exists($file) && !is_writable($file)))
	    {
	      throw new Vega_Log_Exception('{'.__CLASS__.'} '.sprintf('Unable to open the log file "%s" for writing', $file));
	    }
	
		if (!is_dir($dir))
	    {
	      	mkdir($dir, 0777, 1);
	    }
		
		if (!file_exists($file))
	    {
	      	chmod($file, 0666);
	    }
	    
	    // rename file if filesize is too big
	    if (filesize($file) > $this->_maxFilesize)
	    {
            $memoryLimit = @ini_get("memory_limit");
            @ini_set("memory_limit", "32M");

            $filename       = basename($file);
            $newFilename    = $filename . '_' . date('YmdHis');
            $newFile        = $dir . DIRECTORY_SEPARATOR . $newFilename;
	    	rename($file, $newFile);
        
            if($compress) @shell_exec('cd ' . $dir . ';tar -czvf ' . $newFilename . '.tar.gz ' . $newFilename . ';rm -f ' . $newFilename);

            @ini_set("memory_limit", $memoryLimit);
	    }

	    if(!$this->_fHandle = @fopen($file, $mode))
	    {
	    	$msg = "\"$this->_fHandle\" cannot be opened with mode \"$mode\"";
            throw new Vega_Log_Exception('{'.__CLASS__.'} '.$msg);
	    }
	    else
	    {
            if (get_resource_type($this->_fHandle) != 'stream') {
                throw new Vega_Log_Exception('{'.__CLASS__.'} Resource is not a stream');
            }

            if ($mode != 'a') {
                throw new Vega_Log_Exception('{'.__CLASS__.'} Mode cannot be changed on existing streams');
            }
        } 

        $this->_filesize	= filesize($file);    
		$this->_file 		= $file;
	}

	public function write($logEntry) 
	{
		$line = $this->_formatLog($logEntry);
		
		// write to file
		if (false === @fwrite($this->_fHandle, $line)) {
            throw new Vega_Log_Exception('{'.__CLASS__.'} Unable to write to file');
        }
	}

	public function shutdown() 
	{
		if ($this->_fHandle)
		{
			fclose($this->_fHandle);
		}
	}
	
	public function setFormat($format)
	{
		$this->_format	= $format;
	}
	
	protected function _formatLog($logEntry)
	{
		$format = $this->_format;
		
		if (is_array($logEntry)) {
			if (!$format)
			{
				$format = "%s %s [%s] %s %s%s";		// timestamp, app, level, message and extras
			}
			
			return sprintf($format, $logEntry['timestamp'], $logEntry['app'], $logEntry['level'], $logEntry['message'], $logEntry['extras'], DIRECTORY_SEPARATOR == '\\' ? "\r\n" : "\n");
		}
		else {
			if (!$format) $format = "%s";
			return sprintf($format.(DIRECTORY_SEPARATOR == '\\' ? "\r\n" : "\n"), $logEntry);
		}					
	}
}